package kr.co.valueworks.fishing.activity;

import java.util.ArrayList;
import java.util.List;

import kr.co.valueworks.fishing.R;
import kr.co.valueworks.fishing.model.FishingDBHelper;
import kr.co.valueworks.fishing.model.FishingInfo;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.drawable.Drawable;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import com.google.android.maps.MapView.LayoutParams;

public class MyFishingMap extends MapActivity implements LocationListener{

	final int INITIAL_ZOOM_LEVEL = 16;
	final int AROUND_LIMIT = 10000; // Meter
	
	boolean isLimit = true; // false 일경우 모두 보여준다.
	
    MapView mMap;
    MyLocationOverlay mLocation;
	LocationManager locManager;
	String bestProvider;
	Location currentLocation; //현재 위치

    FishingDBHelper fishingDBHelpler;
    
    ArrayList<FishingInfo> fishingList;
    
	Double fromLatitude = 0.0;
	Double toLatitude = 0.0;
	Double fromLogitude = 0.0;
	Double toLogitude = 0.0;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.fishing_map);

        fishingList = new ArrayList<FishingInfo>();
        
        mMap = (MapView)findViewById(R.id.fishingMapView);
        MapController mapControl = mMap.getController();
        mapControl.setZoom(INITIAL_ZOOM_LEVEL);
        mMap.setBuiltInZoomControls(true);
        		
        checkProvider();
        currentLocation = locManager.getLastKnownLocation(bestProvider);
        locManager.requestLocationUpdates(bestProvider, 10000, 100, this); 	

        showMyLocation();
        getAroundingFishing(currentLocation);
        
		addFishingOverLay();	
        
		// 현재 위치 아이콘
        ImageButton myloc = (ImageButton)findViewById(R.id.locImageButton);
		myloc.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v){
				if(mLocation.getMyLocation() != null)
					mMap.getController().animateTo(mLocation.getMyLocation());
			}
		});
		
		// 리스트 아이콘
        ImageButton listButton = (ImageButton)findViewById(R.id.listImageButton);
        listButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v){			
				Intent intent = new Intent(MyFishingMap.this, Fishing.class);
	    		intent.putExtra("fromLatitude", fromLatitude.toString());
	    		intent.putExtra("toLatitude", toLatitude.toString());
	    		intent.putExtra("fromLogitude", fromLogitude.toString());
	    		intent.putExtra("toLogitude", toLogitude.toString());
	    		intent.putExtra("type", "map");
				startActivity(intent);	
			}
		});
	}

	protected void addFishingOverLay() {
		if(mMap.getOverlays().size() > 1) mMap.getOverlays().remove(1);
        Drawable spot = getResources().getDrawable(R.drawable.fish);
        spot.setBounds(0, 0, spot.getIntrinsicWidth(),spot.getIntrinsicHeight());
        mMap.getOverlays().add(new FishingOverlay(spot));
	}

	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}

	@Override
	protected void onResume() {
		super.onResume();
		mLocation.enableMyLocation();
		mLocation.enableCompass();	
		
	}
	
	@Override
	protected void onPause() {
		super.onPause();
		mLocation.disableMyLocation();
		mLocation.disableCompass();
		locManager.removeUpdates(this);
	}
	
	@Override
	public void onLocationChanged(Location location) {
		//getAroundingFishing(currentLocation);	
	}

	@Override
	public void onStatusChanged(String provider, int status, Bundle extras) {
	}

	@Override
	public void onProviderEnabled(String provider) {
	}

	@Override
	public void onProviderDisabled(String provider) {		
	}
	
	public void checkProvider() {
		locManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
		Criteria cta = new Criteria();
		cta.setAccuracy(Criteria.ACCURACY_FINE);
		cta.setPowerRequirement(Criteria.POWER_HIGH);
		cta.setAltitudeRequired(false);
		cta.setSpeedRequired(false);
		cta.setCostAllowed(false);
		bestProvider = locManager.getBestProvider(cta, true);
	}
	
	private void updateOverlay()
	{
		//mMap.getOverlays().clear();
		//showMyLocation();
		getAroundingFishing(currentLocation);		
	}
	
	// 현재 위치 표시
	private void showMyLocation() {		
		mLocation = new MyLocationOverlay(this, mMap);
		mMap.getOverlays().add(mLocation);
        
        mLocation.runOnFirstFix(new Runnable() {
            public void run() {
            	if(mLocation.getMyLocation() != null)
            		mMap.getController().animateTo(mLocation.getMyLocation());
            }
        });
        
       // mLocation.d
	}
	
	// 내 위치 주변 좌표 가져오기
	private void getAroundingFishing(Location location)
	{
		if(location == null) return;
	
		try
		{
			String sql = "";
			if(isLimit)
			{
				Double dLatitude = location.getLatitude();
				Double dLongitude = location.getLongitude();
				
				Double squreLat = location.getLatitude();
				Double squreLon = location.getLongitude();
				Location dest = new Location(location);
				float dist = 0f;
				while(true)
				{
					squreLat = dest.getLatitude() + 0.001;
					dest.setLatitude(squreLat);
					dist = location.distanceTo(dest);
					
					//Log.d("Latitude", Float.toString(dist));			
					if(dist > AROUND_LIMIT/2) break;
				}
				dest = new Location(location);
				while(true)
				{
					squreLon = dest.getLongitude() + 0.001;
					dest.setLongitude(squreLon);
					dist = location.distanceTo(dest);
					
					//Log.d("Longitude", Float.toString(dist));			
					if(dist > AROUND_LIMIT/2) break;
				}
				
				fromLatitude = dLatitude - (squreLat - dLatitude);
				toLatitude = squreLat;
				fromLogitude = dLongitude - (squreLon - dLongitude);
				toLogitude = squreLon;
				
				sql = String.format("SELECT * FROM fishing WHERE ( latitude BETWEEN '%s' AND '%s' ) AND ( longitude BETWEEN '%s' AND '%s' ) AND status = 'Y' ", 
						fromLatitude.toString(), toLatitude.toString(), fromLogitude.toString(), toLogitude.toString());			
			}
			else
			{
				sql = String.format("SELECT * FROM fishing AND status = 'Y' ");			
			}
	        fishingDBHelpler = new FishingDBHelper(this);
			Cursor cursor;
			SQLiteDatabase db = fishingDBHelpler.getReadableDatabase();
			
			Log.d("Fishing", sql);
			cursor = db.rawQuery(sql, null);
			
			fishingList.clear();
			while (cursor.moveToNext()) {
				FishingInfo info = new FishingInfo();
				
				String fishingId = cursor.getString(cursor.getColumnIndex("_id"));
				String fishingName = cursor.getString(cursor.getColumnIndex("name"));
				String latitude = cursor.getString(cursor.getColumnIndex("latitude"));
				String longitude = cursor.getString(cursor.getColumnIndex("longitude"));
				String address = cursor.getString(cursor.getColumnIndex("address"));
				String locality = cursor.getString(cursor.getColumnIndex("locality"));
				
				info.setFishingId(fishingId);
				info.setFishingName(fishingName);
				info.setLatitude(latitude);
				info.setLongitude(longitude);
				info.setAddress(address);
				info.setLocality(locality);
				
				Location loc = location;
				loc.setLatitude(Double.parseDouble(latitude));
				loc.setLongitude(Double.parseDouble(longitude));
				
				info.setDistance(location.distanceTo(loc));
				
				fishingList.add(info);

			}
			
			cursor.close();
			fishingDBHelpler.close();
			
			addFishingOverLay();				
		}
		catch(Exception e)
		{
			Toast.makeText(MyFishingMap.this, e.getMessage(), Toast.LENGTH_LONG).show();
		}

	}
	
	class FishingOverlay extends ItemizedOverlay<OverlayItem> {

		public FishingOverlay(Drawable defaultMarker) {
			super(defaultMarker);
			boundCenterBottom(defaultMarker);
			populate();			
		}

		@Override
		protected OverlayItem createItem(int i) {
			OverlayItem item = null;
			
			FishingInfo info = new FishingInfo();
			info = fishingList.get(i);
			
			int lat = (int)(Double.parseDouble(info.getLatitude()) * 1E6);
			int lon =  (int)(Double.parseDouble(info.getLongitude()) * 1E6);

			item = new OverlayItem(new GeoPoint(lat, lon), 
					info.getFishingName(), "");
			
			return  item;
		}

		@Override
		public int size() {
			return fishingList.size();
		}

		@Override
		protected boolean onTap(int index) {
    		String msg;
    		OverlayItem item = getItem(index);
    		msg = item.getTitle();
    		Toast.makeText(MyFishingMap.this, msg, Toast.LENGTH_SHORT).show();
    		return true;
		}

		@Override
		public boolean onTap(GeoPoint p, MapView mapView) {
			Location location = new Location("");
			location.setLatitude(p.getLatitudeE6() / 1E6);
			location.setLongitude(p.getLongitudeE6() / 1E6);
			getAroundingFishing(location);
			return super.onTap(p, mapView);
		}
		
	}
}
